package affichage;


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.IOException;
import java.awt.Font;

import javax.imageio.ImageIO;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.DataLine.Info;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import deroulementjeu.Partie;


/**
 * Panel ajouté à la fenêtre au lancement du programme, qui affiche les boutons
 * pour lancer une nouvelle partie, charger une partie, editer une carte,
 * ou quitter le programme.
 * @author Alexis BRASY, Geoffrey LEQUESNE, Sandrine PIRIOU, Michel POPOV
 *
 */
public class MenuPrincipal extends JPanel {
	/** Entier nécessaire à la sérialisation */
    private static final long serialVersionUID = 1L;
    /** Le panel vide */
    private PanelVide buts;
    /** Les 4 boutons du menu principal */
    private BoutonChoix newGame, charger, editer, quitter;
    /** Les deux entiers servant à donner la dimension des boutons */
    private static final int dimensionButX = 340;
    private static final int dimensionButY = 37;
    /** La partie */
    private Partie p;
    /** La fenêtre où on affiche le menu principal */
    private Fenetre f;
    /** L'EditeurView la fenêtre appelée lors du clique sur le bouton "editer" */
    private EditeurView e;
    /** Le JeuView la fenêtre appelée lors du clique sur le bouton "nouvelle partie" */
    private JeuView j;
    /** Le thread qui lancera le son */
    private SoundThread st;
	
    /**
     * Le constructeur du menu principal
     * @param p la partie
     * @param fen la fenêtre où on affiche le menu principal
     */
    public MenuPrincipal(Partie p, Fenetre fen) {
        this.f = fen;
        this.p = p;
        this.setBackground(Color.red);
        buts = new PanelVide();
        PanelVide img = new PanelVide();

        img.setBackground(Color.white);
		
        img.setPreferredSize(
                new Dimension(fen.getWidth(),
                fen.getHeight() - 6 * dimensionButY));
        this.add(img, BorderLayout.NORTH);
        this.f.setResizable(false);
		
        buts.setPreferredSize(new Dimension(dimensionButX, 5 * dimensionButY));
        newGame = new BoutonChoix("Nouvelle Partie");
        charger = new BoutonChoix("Charger Partie");
        editer = new BoutonChoix("Editer une map");
        quitter = new BoutonChoix("Quitter");
        this.add(buts, BorderLayout.SOUTH);
        buts.add(newGame, BorderLayout.SOUTH);
        buts.add(charger, BorderLayout.SOUTH);
        buts.add(editer, BorderLayout.SOUTH);
        buts.add(quitter, BorderLayout.SOUTH);
		
        // On lance la musique de départ
        st = new SoundThread();
        st.start();
		
    }
	
    /**
     * Getter du thread du son
     * @return le soundthread
     */
    public SoundThread getSoundThread() {
        return st;
    }

    /**
     * La méthode paintComponent qui affiche l'image de fond
     */
    public void paintComponent(Graphics g) {
		
        try {
            Image img = ImageIO.read(new File("img/imgmenu.jpg"));

            g.drawImage(img, 0, 0, this);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
	
    /**
     * La méthode qui lance un nouveau thread du son qui avait été arrêté
     */
    public void relancerSound() {
        st = new SoundThread();
        st.start();
    }
	
    /**
     * Classe d'un panel vide
     * @author Alexis BRASY, Geoffrey LEQUESNE, Sandrine PIRIOU, Michel POPOV
     *
     */
    class PanelVide extends JPanel {
        private static final long serialVersionUID = 1L;

        /**
         * Constructeur vide du panel vide
         */
        public PanelVide() {}
		
        /**
         * Méthode paintComponent vide
         */
        public void paintComponent(Graphics g) {}
    }
	
    /**
     * Classe d'un bouton affiché sur le menu principal
     * @author Alexis BRASY, Geoffrey LEQUESNE, Sandrine PIRIOU, Michel POPOV
     *
     */
    class BoutonChoix extends JButton implements MouseListener {
    	/** Entier nécessaire à la sérialisation */
        private static final long serialVersionUID = 1L;
        /** Le titre du bouton */
        private String name;
        /** L'image à afficher sur le bouton */
        private Icon icon;
	       
        /**
         * Constructeur du BoutonChoix 
         * @param str le titre du bouton
         */
        public BoutonChoix(String str) {
            super(str);
            this.name = str;
            this.setBorder(null);
            
            new Font("Arial Black", Font.PLAIN, 16);
            this.addMouseListener(this);
            
            if (name.equals("Nouvelle Partie")) {
                icon = new ImageIcon("img/nouvellepartie.jpg");
            } else if (name.equals("Charger Partie")) {
                icon = new ImageIcon("img/charger.jpg");
            } else if (name.equals("Editer une map")) {
                icon = new ImageIcon("img/editer.jpg");
            } else if (name.equals("Quitter")) {
                icon = new ImageIcon("img/quitter.jpg");
            }
            
            this.setPreferredSize(
                    new Dimension(icon.getIconWidth(), icon.getIconHeight()));
        }
   
        /**
         * Redéfinition de la méthode paintComponent
         * On affiche l'image du bouton
         */
        public void paintComponent(Graphics g) {
            icon.paintIcon(this, g, 0, 0);
        }

        /**
         * Redéfinition de la méthode mouseClicked lorsque l'on clique sur la souris
         */
        @SuppressWarnings("deprecation")
        @Override
        public void mouseClicked(MouseEvent event) {
            st.stop();
            if (event.getSource() == newGame) {
                f.setVisible(false);
               
                Dialog init = new Dialog(null, "Initialisation du jeu", true);
   			
                DialogInfo Info = init.showDialog();

                p.getRegle().setModeScenario(Info.getModeScenario());
                p.getRegle().setModeCombat(Info.getModeCombat());
   			
                p.getRegle().setRegenPV(Info.getRegen());
                p.getRegle().setXpMortel(Info.getXpMortel());
                p.getRegle().setDepPostMortem(Info.getDepPostMortem());
                p.getRegle().setNbPotion(Info.getNbPotion());
                p.getRegle().setNivIA(Info.getIaNiveau());
                p.setTypeJoueur(1, Info.getIa());
    		   
                JOptionPane.showMessageDialog(null,
                        "Choisissez une carte pour jouer", "Information",
                        JOptionPane.INFORMATION_MESSAGE);
           	
                TerrainView pan = new TerrainView(p, f, false);

                pan.setPreferredSize(
                        new Dimension(
                                pan.getTerrain().getNbColonnes()
                                        * pan.getCaseTerrainView().get(0).get(0).getHexaWidth()
                                                + pan.getCaseTerrainView().get(0).get(0).getHexaWidth()
                                                        / 2,
                                                        pan.getTerrain().getNbLignes()
                                                                * pan.getCaseTerrainView().get(0).get(0).getHexaSide()
                                                                        + pan.getCaseTerrainView().get(0).get(0).getHexaHeight()
                                                                        - pan.getCaseTerrainView().get(0).get(0).getHexaSide()));
    		   
                j = new JeuView(p, f, false);
                j.setVisible(true);
            } else if (event.getSource() == charger) {
                f.setVisible(false);
                JFileChooser fileChooser = new JFileChooser("partiesSauv/");
                ChoixFichier filtre = new ChoixFichier(".sav",
                        "Fichier Partie Sauvegardée");
                File file;

                fileChooser.addChoosableFileFilter(filtre);
	        	
                if (fileChooser.showOpenDialog(null)
                        == JFileChooser.APPROVE_OPTION) {
                    // On ajoute notre filtre sur l'objet fileChooser !
                    file = fileChooser.getSelectedFile();
                    // Si l'extension est valide
                    Partie newP = p.charger("partiesSauv/" + file.getName());
					
                    /*
                    System.out.println(
                            "DimTerChargé : " + newP.getTerrain().getNbLignes()
                            + "x" + newP.getTerrain().getNbColonnes());
                    */

                    j = new JeuView(newP, f, true);
                    j.setVisible(true);
					
                }
            } else if (event.getSource() == editer) {
                f.setVisible(false);
                e = new EditeurView(p, f);
                e.setVisible(true);
            } else if (event.getSource() == quitter) {
                System.exit(0);
            }
        }

        /**
         * Redéfinition de la méthode mouseEntered
         * On affiche une nouvelle image lorsque la souris entre dans le bouton
         */
        @Override
        public void mouseEntered(MouseEvent event) {
               
            // Nous changeons le fond en jaune pour notre image lors du survol
            // avec le fichier fondBoutonHover.png
            // color=Color.red;
            if (name.equals("Nouvelle Partie")) {
                icon = new ImageIcon("img/nouvellepartieselec.jpg");
            } else if (name.equals("Charger Partie")) {
                icon = new ImageIcon("img/chargerselec.jpg");
            } else if (name.equals("Editer une map")) {
                icon = new ImageIcon("img/editerselec.jpg");
            } else if (name.equals("Quitter")) {
                icon = new ImageIcon("img/quitterselec.jpg");
            }
        }

        /**
         * Redéfinition de la méthode mouseExited
         * On affiche une nouvelle image lorsque la souris sors du bouton
         */
        @Override
        public void mouseExited(MouseEvent event) {

            // color=Color.yellow;
            if (name.equals("Nouvelle Partie")) {
                icon = new ImageIcon("img/nouvellepartie.jpg");
            } else if (name.equals("Charger Partie")) {
                icon = new ImageIcon("img/charger.jpg");
            } else if (name.equals("Editer une map")) {
                icon = new ImageIcon("img/editer.jpg");
            } else if (name.equals("Quitter")) {
                icon = new ImageIcon("img/quitter.jpg");
            }
               
        }

        @Override
        public void mousePressed(MouseEvent event) {}

        @Override
        public void mouseReleased(MouseEvent event) {}       
    }
	

    /**
     * Classe pour lire un son
     * @author Alexis BRASY, Geoffrey LEQUESNE, Sandrine PIRIOU, Michel POPOV
     *
     */
    class Sound {
        public void readAudioFile(String fileName) {
            try {
                AudioInputStream ais = AudioSystem.getAudioInputStream(
                        new File(fileName));
                AudioFormat format = ais.getFormat();
                Info info = new Info(SourceDataLine.class, format);
                SourceDataLine source = (SourceDataLine) AudioSystem.getLine(
                        info);

                source.open(format);
                source.start();
                int read = 0;
                byte[] audioData = new byte[16384];

                while (read > -1) {
                    read = ais.read(audioData, 0, audioData.length);
                    if (read >= 0) {
                        source.write(audioData, 0, read);
                    }
                }
                source.drain();
                source.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
	    
        }
    }
	
    /**
     * Classe pour lire le son dans le menu principal
     * @author Alexis BRASY, Geoffrey LEQUESNE, Sandrine PIRIOU, Michel POPOV
     *
     */
    class SoundThread extends Thread {
        
        public void run() {
            new Sound().readAudioFile("sound/menu.wav");
        }
    }
	
}

